package cn.zpon.pay.demo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;

import cn.zpon.pay.demo.util.ApacheHttpClient;
import cn.zpon.pay.demo.util.EncryptUtil;
import cn.zpon.pay.demo.util.HttpResponse;

/**
 * 收银猿服务器端demo，仅供参考

 * @author davy
 *
 */
@RestController
@RequestMapping(value = "/api", produces = "application/json;charset=UTF-8")
public class ApiController {
    
    protected Logger log = LoggerFactory.getLogger(getClass());
    
    private ApacheHttpClient httpclient = new ApacheHttpClient();

//    private String apidomain = "http://127.0.0.1:8080";
    private String apidomain = "https://pay1.17f.cn"; //API域名，调测环境为：http://pay1.17f.cn，正式环境为https://pay.17f.cn
    private String appid = "200";            //收银猿分配的appid
    private String appSecret = "1234567890"; //收银猿分配的appsecret
    
    @RequestMapping(path = "/pay", method = RequestMethod.POST)
    public String pay(HttpServletRequest request) {
        String url = apidomain + "/openapi/order/create";  
        Map<String, String> nameValues = new HashMap<>();
        nameValues.put("amount", request.getParameter("amount"));  //金额，单位为：分
        nameValues.put("appid", appid);
        nameValues.put("order_no", String.valueOf(System.currentTimeMillis())); //订单号，同一商户唯一
        nameValues.put("channel", request.getParameter("channel"));  //支付渠道，微信：wx，支付宝：alipay
        nameValues.put("subject", request.getParameter("subject"));  //标题
        if (request.getParameter("body") != null) {
            nameValues.put("body", request.getParameter("body"));    //内容    
        }
        nameValues.put("ip", request.getRemoteAddr());               //用户IP地址
        nameValues.put("custrom_data", "{\"id\":12356}");            //定制内容，支付通知原样返回
        nameValues.put("sign", createSign(nameValues));

        JSONObject json = new JSONObject();
        json.put("code", 0);
        HttpResponse resp = httpclient.post(url, nameValues);
        if (resp.isOk()) {
            JSONObject respJson = JSONObject.parseObject(resp.getResponse());
            if (respJson.getIntValue("code") == 1) {
                json.put("code", 1);    
                json.put("data", respJson.getJSONObject("data"));
            } else {
                json.put("msg", respJson.getString("msg"));
            }
        }
        return json.toJSONString();
    }
    
    @RequestMapping(path = "/pay/notify", method = RequestMethod.POST)
    public String payNotify(HttpServletRequest request) {
        LinkedHashMap<String, String> params = getRequestParams(request);
        boolean ok = isSignOk(params, params.remove("sign"));
        String appid = request.getParameter("appid");
        String ret_code = request.getParameter("ret_code");
        String order_no = request.getParameter("order_no");
        String order_no_syy = request.getParameter("order_no_syy");
        String custrom_data = request.getParameter("custrom_data");
        log.info("payNotify, sign ok:{}, appid:{}, ret_code:{}, order_no:{}, order_no_syy:{}, custrom_data:{}", 
            ok, appid, ret_code, order_no, order_no_syy, custrom_data);
        return "{\"code\":" + (ok ? "1" : "0") + "}";
    }
    
    private LinkedHashMap<String, String> getRequestParams(HttpServletRequest request) {
        Enumeration<String> names = request.getParameterNames();
        List<String> list = new ArrayList<String>();
        while (names.hasMoreElements()) {
            list.add(names.nextElement());
        }
        Collections.sort(list);

        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
        for (String name : list) {
            map.put(name, request.getParameter(name));
        }
        return map;
    }
    
    private boolean isSignOk(LinkedHashMap<String, String> params, String sign) {
        return createSign(params).equals(sign);
    }
    
    private String createSign(Map<String, String> params) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        
        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            String value = params.get(key);
            if (value != null) {
                sb.append(key).append("=").append(value).append("&");    
            }
        }
        sb.append("key=").append(appSecret);
        log.info("createSign:{}", sb);
        return EncryptUtil.md5(sb.toString()).toUpperCase();
    }
}
